#region Microsoft Public License
/*
 * (c) Copyright Chenjun Wu. http://utablesdk.codeplex.com
 * 
 * This source is subject to the Microsoft Public License (Ms-PL).
 * Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
 * All other rights reserved.
 */
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Media;
using System.Windows;

namespace UTable.Objects.Controls
{
	public partial class UBookPage
	{
        private static PageParameters ResetPage(UIElement source, CornerOrigin origin) {
            PageParameters _parameters = new PageParameters(source.RenderSize);
            _parameters.Page0ShadowOpacity = 0;
            _parameters.Page1ClippingFigure = new PathFigure();
            _parameters.Page1ReflectionStartPoint = new Point(0, 0);
            _parameters.Page1ReflectionEndPoint = new Point(0, 0);
            _parameters.Page1RotateAngle = 0;
            _parameters.Page1RotateCenterX = 0;
            _parameters.Page1RotateCenterY = 0;
            _parameters.Page1TranslateX = 0;
            _parameters.Page1TranslateY = 0;
            _parameters.Page2ClippingFigure = new PathFigure();
            _parameters.Page0ShadowStartPoint = new Point(0, 0);
            _parameters.Page0ShadowEndPoint = new Point(0, 0);

            return _parameters;
        }
        
        private static double epsilon = 0.001;

        private static PageParameters? ComputePage(UIElement source, Point p, Point origin)
        {
            CheckParams(ref source, ref p, origin);

            double reStartx = 1 - (origin.X + p.X) / 2 / source.RenderSize.Width;
            double reStarty = (origin.Y + p.Y) / 2.0 / source.RenderSize.Height;
            double reEndx = 1 - origin.X / source.RenderSize.Width;
            double reEndy = origin.Y / source.RenderSize.Height;

            double shStartx = 1 - reStartx;
            double shStarty = reStarty;
            double shEndx = 1 - (2 * reStartx - reEndx);
            double shEndy = 2 * reStarty - reEndy;
          //  double page0ShadowStartx = 


            PageParameters _parameters = new PageParameters(source.RenderSize);

            double ratio = ComputeProgressRatio(source, p, origin);
            if (ratio > 1.5)
                ratio = (2 - ratio) / 0.5;
            else
                ratio = 1;

            _parameters.Page0ShadowOpacity = ratio;

            if (origin.X == source.RenderSize.Width)
            {

                double xc = source.RenderSize.Width;
                double yc = source.RenderSize.Height;
                double epsilon = 0.01;
                double xx = xc - p.X;
                if (xx == 0)
                    xx += epsilon;
                double yy = p.Y - origin.Y;
                if (yy == 0)
                    yy += epsilon;
                double angle1 = (Math.Atan((yy) / (xx))) * 180 / Math.PI;
                double angle = -2 * angle1;

                if (angle > 0)
                {
                    double xxx = (origin.X + p.X) / 2 + (yc - (origin.Y + p.Y) / 2) / xx * yy;
                    double yyy = (xc - xxx) / yy * xx + yc;

                    _parameters.Page1ClippingFigure.StartPoint = new Point(0, yc);
                    _parameters.Page1ClippingFigure.Segments.Clear();
                    _parameters.Page1ClippingFigure.Segments.Add(new LineSegment(new Point(0, yyy), false));
                    _parameters.Page1ClippingFigure.Segments.Add(new LineSegment(new Point(xc - xxx, yc), false));


                    _parameters.Page1RotateAngle = angle;
                    _parameters.Page1RotateCenterX = xxx;
                    _parameters.Page1RotateCenterY = yc;
                    _parameters.Page1TranslateX = 2 * xxx - xc;
                    _parameters.Page1TranslateY = 0;
                }
                else
                {
                    double xxx = (origin.X + p.X) / 2 - (origin.Y + p.Y) / 2 / xx * yy;
                    double yyy = (xc - xxx) / yy * xx;

                    _parameters.Page1ClippingFigure.StartPoint = new Point(0, 0);
                    _parameters.Page1ClippingFigure.Segments.Clear();
                    _parameters.Page1ClippingFigure.Segments.Add(new LineSegment(new Point(xc - xxx, 0), false));
                    _parameters.Page1ClippingFigure.Segments.Add(new LineSegment(new Point(0, yyy), false));

                    _parameters.Page1RotateAngle = angle;
                    _parameters.Page1RotateCenterX = xxx;
                    _parameters.Page1RotateCenterY = 0;
                    _parameters.Page1TranslateX = 2 * xxx - xc;
                    _parameters.Page1TranslateY = 0;
                }


                _parameters.Page2ClippingFigure.StartPoint = new Point(xc - _parameters.Page1ClippingFigure.StartPoint.X, _parameters.Page1ClippingFigure.StartPoint.Y);

                _parameters.Page2ClippingFigure.Segments = _parameters.Page1ClippingFigure.Segments.Clone();
                ((LineSegment)_parameters.Page2ClippingFigure.Segments[0]).Point
                    = new Point(xc - ((LineSegment)_parameters.Page2ClippingFigure.Segments[0]).Point.X,
                        ((LineSegment)_parameters.Page2ClippingFigure.Segments[0]).Point.Y);
                ((LineSegment)_parameters.Page2ClippingFigure.Segments[1]).Point
                    = new Point(xc - ((LineSegment)_parameters.Page2ClippingFigure.Segments[1]).Point.X,
                        ((LineSegment)_parameters.Page2ClippingFigure.Segments[1]).Point.Y);
            }
            else
            {
                p.X = source.RenderSize.Width - p.X;
                origin.X = source.RenderSize.Width - origin.X;

                double xc = source.RenderSize.Width;
                double yc = source.RenderSize.Height;
                double epsilon = 0.01;
                double xx = xc - p.X;
                if (xx == 0)
                    xx += epsilon;
                double yy = p.Y - origin.Y;
                if (yy == 0)
                    yy += epsilon;
                double angle1 = (Math.Atan((yy) / (xx))) * 180 / Math.PI;
                double angle = -2 * angle1;

                if (angle > 0)
                {
                    double xxx = (origin.X + p.X) / 2 + (yc - (origin.Y + p.Y) / 2) / xx * yy;
                    double yyy = (xc - xxx) / yy * xx + yc;

                    _parameters.Page1ClippingFigure.StartPoint = new Point(xc, yc);
                    _parameters.Page1ClippingFigure.Segments.Clear();
                    _parameters.Page1ClippingFigure.Segments.Add(new LineSegment(new Point(xc, yyy), false));
                    _parameters.Page1ClippingFigure.Segments.Add(new LineSegment(new Point(xxx, yc), false));


                    _parameters.Page1RotateAngle = -angle;
                    _parameters.Page1RotateCenterX = xc - xxx;
                    _parameters.Page1RotateCenterY = yc;
                    _parameters.Page1TranslateX = xc - 2 * xxx ;
                    _parameters.Page1TranslateY = 0;
                }
                else
                {
                    double xxx = (origin.X + p.X) / 2 - (origin.Y + p.Y) / 2 / xx * yy;
                    double yyy = (xc - xxx) / yy * xx;

                    _parameters.Page1ClippingFigure.StartPoint = new Point(xc, 0);
                    _parameters.Page1ClippingFigure.Segments.Clear();
                    _parameters.Page1ClippingFigure.Segments.Add(new LineSegment(new Point(xxx, 0), false));
                    _parameters.Page1ClippingFigure.Segments.Add(new LineSegment(new Point(xc, yyy), false));

                    _parameters.Page1RotateAngle = -angle;
                    _parameters.Page1RotateCenterX = xc - xxx;
                    _parameters.Page1RotateCenterY = 0;
                    _parameters.Page1TranslateX = xc - 2 * xxx ;
                    _parameters.Page1TranslateY = 0;
                }


                _parameters.Page2ClippingFigure.StartPoint = new Point(xc - _parameters.Page1ClippingFigure.StartPoint.X, _parameters.Page1ClippingFigure.StartPoint.Y);

                _parameters.Page2ClippingFigure.Segments = _parameters.Page1ClippingFigure.Segments.Clone();
                ((LineSegment)_parameters.Page2ClippingFigure.Segments[0]).Point
                    = new Point(xc - ((LineSegment)_parameters.Page2ClippingFigure.Segments[0]).Point.X,
                        ((LineSegment)_parameters.Page2ClippingFigure.Segments[0]).Point.Y);
                ((LineSegment)_parameters.Page2ClippingFigure.Segments[1]).Point
                    = new Point(xc - ((LineSegment)_parameters.Page2ClippingFigure.Segments[1]).Point.X,
                        ((LineSegment)_parameters.Page2ClippingFigure.Segments[1]).Point.Y);

            }
/*
            Point refletStartPoint;
            Point refletEndPoint;*/

          /*  CornerOrigin oppositeOrigin = CornerOrigin.TopLeft;
            switch (origin)
            {
                case CornerOrigin.BottomLeft:
                    oppositeOrigin = CornerOrigin.BottomRight;
                    break;
                case CornerOrigin.BottomRight:
                    oppositeOrigin = CornerOrigin.BottomLeft;
                    break;
                case CornerOrigin.TopLeft:
                    oppositeOrigin = CornerOrigin.TopRight;
                    break;
                case CornerOrigin.TopRight:
                    oppositeOrigin = CornerOrigin.TopLeft;
                    break;
            }

            LinearGradientHelper.ComputePointsFromTop(xc, yc, xc - l1, yc - h1, 20, 20,
                oppositeOrigin,
                out refletStartPoint,
                out refletEndPoint);
            */

            
            _parameters.Page1ReflectionStartPoint = new Point(reStartx, reStarty);// refletStartPoint;
            _parameters.Page1ReflectionEndPoint = new Point(reEndx,reEndy);// refletEndPoint; //new Point(1, 1 / Math.Tan((90 - angleClipping) * Math.PI / 180));

            _parameters.Page0ShadowStartPoint = new Point(shStartx, shStarty);
            _parameters.Page0ShadowEndPoint = new Point(shEndx, shEndy);
            
            /*
            Point startPoint;
            Point endPoint;

            double d = Math.Sqrt(Math.Pow(p.X - xc, 2) + Math.Pow(p.Y - yc, 2));

            double r1 = d / 10;
            double r2 = d / 10;

            LinearGradientHelper.ComputePoints(xc, yc, xc - l1, yc - h1, r1, r2,
                origin, out startPoint, out endPoint);
            */
           // _parameters.Page0ShadowStartPoint = // startPoint;
           // _parameters.Page0ShadowEndPoint = origin;

            return _parameters;
        }

        private static void CheckParams(ref UIElement source, ref Point p, Point origin) {
            if (p.Y == origin.Y)
                p.Y += 0.01;
            if (origin.X == source.RenderSize.Width)
            {
                double dx = p.X;
                double dy = p.Y - source.RenderSize.Height;
                double R = Math.Sqrt(source.RenderSize.Width * source.RenderSize.Width + (source.RenderSize.Height - origin.Y) * (source.RenderSize.Height - origin.Y));
                double d = Math.Sqrt(dx * dx + dy * dy);
                if (d > R)
                {
                    dx = dx * R / d;
                    dy = dy * R / d;
                }
                p.X = dx;
                p.Y = source.RenderSize.Height + dy;


                d = Math.Sqrt(p.X * p.X + p.Y * p.Y);
                R = Math.Sqrt(source.RenderSize.Width * source.RenderSize.Width + (origin.Y) * (origin.Y));
                if (d > R)
                {
                    double x = p.X * R / d;
                    double y = p.Y * R / d;
                    p.X = x;
                    p.Y = y;
                }
            }
            else
            {
                p.X = source.RenderSize.Width - p.X;
                Point temp = origin;
                temp.X = source.RenderSize.Width;
                CheckParams(ref source, ref p,temp);
                p.X = source.RenderSize.Width - p.X;
            }
  

        }
	}
}
